package com.kuizii.base.common.configs;



import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.converter.BidirectionalConverter;
import ma.glasnost.orika.metadata.Type;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.PostConstruct;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * @Author: nuanyang
 * @Date: 2019/12/11 0011 16:11
 */
@Configuration
@ConditionalOnClass(value = MapperFactory.class)
@AutoConfigureAfter({MapperFacotoryAutoWire.class})
public class OrikaConfig {

    @Autowired
    private MapperFactory mapperFactory;

    /**
     * 解决orika映射LocalDateTime报错问题
     */
    @PostConstruct
    public void init() {
        mapperFactory.getConverterFactory().registerConverter(new LocalDateTimeConverter());
        mapperFactory.getConverterFactory().registerConverter(new LocalDateConverter());
        mapperFactory.getConverterFactory().registerConverter(new LocalTimeConverter());
        mapperFactory.getConverterFactory().registerConverter(new LocalDateTimeToDateConvert());
    }

    private class LocalDateTimeConverter extends BidirectionalConverter<LocalDateTime, LocalDateTime> {

        @Override
        public LocalDateTime convertTo(LocalDateTime localDateTime, Type<LocalDateTime> type, MappingContext mappingContext) {
            return LocalDateTime.from(localDateTime);
        }

        @Override
        public LocalDateTime convertFrom(LocalDateTime localDateTime, Type<LocalDateTime> type, MappingContext mappingContext) {
            return LocalDateTime.from(localDateTime);
        }
    }

    private class LocalDateConverter extends BidirectionalConverter<LocalDate, LocalDate> {


        @Override
        public LocalDate convertTo(LocalDate localDate, Type<LocalDate> type, MappingContext mappingContext) {
            return LocalDate.from(localDate);
        }

        @Override
        public LocalDate convertFrom(LocalDate localDate, Type<LocalDate> type, MappingContext mappingContext) {
            return LocalDate.from(localDate);
        }
    }

    private class LocalTimeConverter extends BidirectionalConverter<LocalTime, LocalTime> {
        @Override
        public LocalTime convertTo(LocalTime source, Type<LocalTime> destinationType, MappingContext mappingContext) {
            return LocalTime.from(source);
        }

        @Override
        public LocalTime convertFrom(LocalTime source, Type<LocalTime> destinationType, MappingContext mappingContext) {
            return LocalTime.from(source);
        }
    }

    public class LocalDateTimeToDateConvert extends BidirectionalConverter<Date, LocalDateTime> {

        @Override
        public LocalDateTime convertTo(Date date, Type<LocalDateTime> type, MappingContext mappingContext) {
            return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
        }

        @Override
        public Date convertFrom(LocalDateTime localDateTime, Type<Date> type, MappingContext mappingContext) {
            return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        }
    }
}
